<?php
declare (strict_types=1);

namespace app\admin\logic\user;

use app\admin\logic\system\Log;
use app\admin\model\user\Account;
use app\admin\model\user\Group as UserGroupModel;
use app\admin\model\user\GroupAccess;
use app\common\exception\LogicException;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;

class Group extends UserGroupModel
{
    /**
     * 创建角色
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-17
     *
     * @param array $group [description]
     */
    public function createGroup(array $group): self
    {
        // 验证数据
        $this->getValidate()->scene('create')->failException()->check($group);
        // 用户信息
        $re = $this->save($group);
        // 创建成功
        if (!$re) {
            throw new LogicException('创建失败');
        }

        Log::write('新建角色【' . $group['title'] . '】', 'admin_user', 'create', true);

        return $this;
    }

    /**
     * 编辑角色
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-17
     *
     * @param array $data [description]
     */
    public function editGroup(array $data)
    {
        // 验证数据
        $this->getValidate()->scene('edit')->failException()->check($data);
        // 用户信息
        $group = $this->where('id', $data['id'])->findOrEmpty();
        if ($group->isEmpty()) {
            throw new LogicException('角色信息错误');
        }

        if (!$group->allowField(['title'])->save($data)) {
            throw new LogicException('编辑失败');
        }

        Log::write('编辑角色【' . $group['title'] . '】', 'admin_user', 'update', true);

        return $group;
    }

    /**
     * 删除用户组
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-17
     *
     * @param int $id [description]
     */
    public function deleteGroup(int $id): void
    {
        $group = $this->where('id', $id)->findOrFail();

        Db::startTrans();
        try {
            if (!$group->delete()) {
                throw new LogicException('删除失败');
            }
            $access1 = [
                ['admin_user_group_ids', 'like', '[' . $id . ']']
            ];
            $access2 = [
                ['admin_user_group_ids', 'like', '[' . $id . ',%']
            ];
            $access3 = [
                ['admin_user_group_ids', 'like', '%,' . $id . ',%']
            ];
            $access4 = [
                ['admin_user_group_ids', 'like', '%,' . $id . ']']
            ];
            app(GroupAccess::class)->whereOr([$access1, $access2, $access3, $access4])->select()->each(function ($i) use ($id) {
                $ids   = $i->admin_user_group_ids;
                $index = array_search($id, $ids);
                unset($ids[$index]);
                $i->admin_user_group_ids = $ids;
                if (!$i->save()) throw new LogicException('删除失败');
            });
            Db::commit();
        } catch (LogicException $e) {
            Db::rollback();
            throw new LogicException($e->getMessage());
        }

        Log::write('删除角色【' . $group->title . '】', 'admin_user', 'delete', true);
    }

    /**
     * 获取列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-17
     *
     * @return Group[]|array|Collection [type]                              [description]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getList()
    {
        $list = $this->select();
        if (!$list->isEmpty()) {
            foreach ($list as $group) {
                $group->hasChildren = false;
            }
        }

        return $list;
    }

    /**
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-19
     */
    public function getGroups()
    {
        return $this->scope('fieldTitle')->select();
    }

    /**
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-19
     */
    public function getGroupsWithout2()
    {
        return $this->scope('fieldTitle')->where('id', '<>', '2')->select();
    }

    /**
     * 获取用户组下拉选择数据
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-07-02
     */
    public function getGroupSelect(): array
    {
        return $this->column('title,id as value');
    }

    /**
     * 获取用户组下拉选择数据 - 不包含机构管理员
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-07-02
     */
    public function getGroupSelectWithout2(): array
    {
        return $this->where('id', '<>', '2')->column('title,id as value');
    }

    /**
     * 获取用户组数组，id做键
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-07-02
     */
    public function getGroupsArr(): array
    {
        $data = $this->column('id,title');

        return array_column($data, null, 'id');
    }

    /**
     * 加载用户权限节点
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-22
     *
     * @param Account $user    [description]
     * @param int     $is_menu 对应is_menu的值
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function loadRuleList(Account $user, int $is_menu = 1): array
    {
        if ($user->isSupperAdmin()) {
            // 超级管理员无视配置,获取所有权限
            return Permission::scope('is_menu', $is_menu)->column('permission');
        } else {
            // 当前用户的所有组
            if (!$user->groupAccess || !$user->groupAccess->admin_user_group_ids) {
                return [];
            }
            // 获取该用户所有组的权限规则
            $ruleLists     = $this->withoutGlobalScope(['mhm'])->whereIn('id', $user->groupAccess->admin_user_group_ids)->field('rule_list')->select();
            $permissionIds = [];
            foreach ($ruleLists as $item) {
                $rules = $item->rule_list;
                if (is_array($rules)) {
                    $permissionIds = array_merge($permissionIds, ...$rules);
                }
            }

            return Permission::scope('is_menu', $is_menu)->whereIn('id', $permissionIds)->column('permission');

        }
    }

    /**
     * 设置权限
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-22
     *
     * @param int   $id    用户组ID
     * @param array $auths 包含一个二维数组的权限集 [0=>[],1=>[]]
     */
    public function setAuths(int $id = 0, array $auths = [])
    {
        $group            = $this->where('id', $id)->findOrFail();
        $group->rule_list = $auths;

        if (!$group->save()) throw new LogicException('权限设置失败');

        Log::write('更新角色【' . $group->title . '】权限', 'admin_user', 'update', true);
    }

    /**
     * 获取当前登录用户的权限节点
     *
     * @param null $user
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getCurrentLoginRuleList($user = null): array
    {
        static $permissionIds;
        if (!$permissionIds) {
            $user = is_null($user) ? request()->user : $user;
            if ($user->isSupperAdmin()) {
                // 超级管理员无视配置,获取所有权限
                return Permission::column('id');
            }
            // 当前用户的所有组
            if (!$user->groupAccess || !$user->groupAccess->admin_user_group_ids) {
                return [];
            }
            if (in_array(2, $user->groupAccess->admin_user_group_ids)) {
                // 获取该用户所有组的权限规则
                $ruleLists = $this->withoutGlobalScope(['mhm'])->whereIn('id', $user->groupAccess->admin_user_group_ids)->field('rule_list')->select();
            } else {
                // 获取该用户所有组的权限规则
                $ruleLists = $this->whereIn('id', $user->groupAccess->admin_user_group_ids)->field('rule_list')->select();
            }
            $permissionIds = [];
            foreach ($ruleLists as $item) {
                $rules = $item->rule_list;
                if (is_array($rules)) {
                    $permissionIds = array_merge($permissionIds, ...$rules);
                }
            }
        }

        return $permissionIds;
    }
}
